Coroutine processes are used where the states of two or more activities within a digital system change at different rates and must be maintained simultaneously during a computation. Relatedly, the transfer of control among coroutining processes is itself a complex computation arising from the necessity of saving and retrieving state vector information for both the source and destination processes. In this regard, in the usual calling sequence there is a clear distinction between the calling process and the called process. Transfer of control among (hierarchical) collections of coroutining processes is further complicated from the prior art necessity of a calling process having to possess information descriptive of the internal structure of every process it calls.
As described by A. C. Shaw, "The Logical Design of Operating Systems," Prentiss-Hall, Inc., New York, 1974 at pages 35-37, the calling processes of coroutines are explained by contrasting them will the calling processes of the more familiar subroutines.
In a subroutine program structure, there exists an unsymmetric master/slave relationship between a calling process P and its subroutine. Generally, a subroutine is entered at one of a fixed number of entry points.
All variables that are neither global nor parameters are undefined at entry. In contrast, coroutines are processes that may call each other but do not have this master/slave organization. The relationship between coroutines P and Q is symmetric. Each coroutine is both master and slave. On exit from a coroutine, its state is saved. The next time the coroutine is called, it resumes at exactly the point where it left previously with all of its internal variables unchanged. That is, the previous state of the coroutine is restored. The call on coroutine Q may be designated "RESUME Q". Before a coroutine can be "resumed" for the first time, its state must, of course, be initialized.
It is well appreciated that each coroutine process must be called, perform some work, and then resume some other process or end. Each coroutine call itself saves the address at which it is to resume execution (its resumption point) somewhere for use if it is resumed. This operation may be implemented using an instruction to exchange the top of a stack with instruction counter contents. In such an implementation, an instruction would first pop the old resumption point off the stack into a temporary register, then push the instruction counter onto the stack. Finally, the instruction would transfer the contents of the temporary register into the instruction counter. Since one address is popped off the upper stack and another address is pushed onto it, the stack pointer does not change.
Coroutining can be executed on stack machines such as the Burrough's B5700/B6700 series, as described by Organick, "Computer System Organization", Academic Press, 1973, pages 49 and 54. Alternatively, coroutines can be executed by an emulation equivalent on general register machines, such as the IBM System/370. Other state-of-the-art descriptions of coroutining processes may be found in Wang, et al, "Coroutine Sequencing in a Block Structured Environment", BIT, Vol. 11, 1971, pages 425-449; Hanson, et al, "The SL5 Procedure Mechanism", Communications of the ACM, May 1978, pages 392-400; Bobrow, et al, "A Model and Stack Implementation of Multiple Environments", Communications of the ACM, October 1978, pages 591-602; Knuth, "Fundamental Algorithms", 2nd edition, Addison Wesley, 1973, pages 190-196, and Dickson, U.S. Pat. No. 4,173,782, issued Nov. 6, 1979. These references taken singly or in combination, illustrate that transfer of control among collections of coroutines requires that the calling process has information descriptive of the internal process structure of the called process. Such a requirement complicates the control transfer mechanism and inhibits the modularization (subdividing) of the coroutining processes into subprocesses.